/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.mycompany.delivery.service;

import com.mycompany.delivery.dao.CourierDAO;
import com.mycompany.delivery.dao.DeliveryDAO;
import com.mycompany.delivery.dao.EmployeeDAO;
import com.mycompany.delivery.dto.DeliveryDTO;
import com.mycompany.delivery.dto.UserDTO;
import com.mycompany.delivery.entities.Courier;
import com.mycompany.delivery.entities.Delivery;
import com.mycompany.delivery.entities.Employee;
import com.mycompany.delivery.servicelayer.UserService;
import com.mycompany.delivery.transfers.UserT;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.annotation.Secured;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 *
 * @author akaren
 */
@Service("userServices")
public class UserServiceImpl implements UserService {

    @Autowired
    private EmployeeDAO employeeDao;

    @Autowired
    private CourierDAO courierDao;

    @Autowired
    private DeliveryDAO deliveryDao;

    public EmployeeDAO getEmployeeDao() {
        return employeeDao;
    }

    public void setEmployeeDao(EmployeeDAO employeeDao) {
        this.employeeDao = employeeDao;
    }

    public CourierDAO getCourierDao() {
        return courierDao;
    }

    public void setCourierDao(CourierDAO courierDao) {
        this.courierDao = courierDao;
    }

    public DeliveryDAO getDeliveryDao() {
        return deliveryDao;
    }

    public void setDeliveryDao(DeliveryDAO deliveryDao) {
        this.deliveryDao = deliveryDao;
    }

    @Override
    @Transactional
    @Secured({"ROLE_ADMIN"})
    public UserDTO createEmployee(UserDTO p) {
        if (p == null) {
            throw new IllegalArgumentException("employee is null");
        }
        if (p.getId() != null) {
            throw new IllegalArgumentException("id must be null");
        }

        Employee e = UserT.dTOtoEmployeeEntity(p);
        employeeDao.createEmployee(e);
        p.setId(e.getId());

        return p;
    }

    @Override
    @Transactional
    @Secured({"ROLE_ADMIN"})
    public UserDTO createCourier(UserDTO p) {
        if (p == null) {
            throw new IllegalArgumentException("courier is null");
        }
        if (p.getId() != null) {
            throw new IllegalArgumentException("id must be null");
        }

        Courier c = UserT.dTOtoCourierEntity(p);
        courierDao.createCourier(c);
        p.setId(c.getId());

        return p;
    }

    @Override
    @Transactional
    @Secured({ "ROLE_ADMIN"})
    public UserDTO updateCourier(UserDTO p) {
        if (p == null) {
            throw new IllegalArgumentException("courier is null");
        }
        if (p.getId() == null) {
            throw new IllegalArgumentException("id can't be null");
        }
        courierDao.updateCourier(UserT.dTOtoCourierEntity(p));
        return p;
    }

    @Override
    @Transactional
    @Secured({ "ROLE_ADMIN"})
    public UserDTO updateEmployee(UserDTO p) {
        if (p == null) {
            throw new IllegalArgumentException("employee is null");
        }
        if (p.getId() == null) {
            throw new IllegalArgumentException("id can't be null");
        }
        employeeDao.updateEmployee(UserT.dTOtoEmployeeEntity(p));
        return p;
    }

    @Override
    @Transactional
    @Secured({ "ROLE_ADMIN"})
    public void remove(String login) {
        if (login == null) {
            throw new IllegalArgumentException("login is null");
        }
        Employee emp = employeeDao.getEmployeeByLogin(login);
        Courier cou = courierDao.getCourierByLogin(login);
        if (emp != null) {
            removeEmployee(UserT.EntityToDTO(emp));
        } else if (cou != null) {
            removeCourier(UserT.EntityToDTO(cou));
        }
    }

    @Override
    @Transactional
    @Secured({ "ROLE_ADMIN"})
    public void removeCourier(UserDTO p) {
        if (p == null) {
            throw new IllegalArgumentException("courier is null");
        }
        if (p.getId() == null) {
            throw new IllegalArgumentException("id can't be null");
        }
        Courier c = courierDao.getCourierById(p.getId());
        for (Delivery del : c.getDeliveries()) {
            del.setCourier(null);
            deliveryDao.updateDelivery(del);
        }

        courierDao.deleteCourier(UserT.dTOtoCourierEntity(p));
    }

    @Override
    @Transactional
    @Secured({ "ROLE_ADMIN"})
    public void removeEmployee(UserDTO p) {
        if (p == null) {
            throw new IllegalArgumentException("courier is null");
        }
        if (p.getId() == null) {
            throw new IllegalArgumentException("id can't be null");
        }
        Employee c = employeeDao.getEmployeeById(p.getId());
        for (Delivery del : c.getCreatedDelivery()) {
            del.setCourier(null);
            deliveryDao.updateDelivery(del);
        }

        employeeDao.deleteEmployee(UserT.dTOtoEmployeeEntity(p));
    }

    @Override
    @Transactional
   @Secured({"ROLE_EMPL", "ROLE_COUR", "ROLE_ADMIN"})
    public UserDTO findCourier(Long id) {
        if (id == null) {
            throw new IllegalArgumentException("id is null");
        }
        Courier cou = courierDao.getCourierById(id);
        if (cou != null) {
            return UserT.EntityToDTO(cou);
        }
        return null;
    }

    @Override
    @Transactional
    @Secured({"ROLE_EMPL", "ROLE_COUR", "ROLE_ADMIN"})
    public UserDTO findEmployee(Long id) {
        if (id == null) {
            throw new IllegalArgumentException("id is null");
        }
        Employee emp = employeeDao.getEmployeeById(id);
        if (emp != null) {
            return UserT.EntityToDTO(emp);
        }
        return null;
    }

    @Override
    @Transactional
    @Secured({"ROLE_EMPL", "ROLE_COUR",  "ROLE_ADMIN"})
    public UserDTO findUserByLogin(String login) {
        if (login == null) {
            throw new IllegalArgumentException("login is null");
        }
        Employee emp = employeeDao.getEmployeeByLogin(login);

        if (emp != null) {
            return UserT.EntityToDTO(emp);
        }
        Courier cou = courierDao.getCourierByLogin(login);

        if (cou != null) {
            return UserT.EntityToDTO(cou);
        }
        return null;
    }

    @Override
    @Transactional
    @Secured({"ROLE_ADMIN"})
    public List<UserDTO> getAllUsers() {
        List<UserDTO> users = new ArrayList<UserDTO>();
        for (Courier c : courierDao.getAllCouriers()) {
            users.add(UserT.EntityToDTO(c));
        }
        for (Employee e : employeeDao.getAllEmployees()) {
            users.add(UserT.EntityToDTO(e));
        }
        return users;

    }

    @Override
    @Transactional
    @Secured({"ROLE_EMPL", "ROLE_COUR", "ROLE_ADMIN"})
    public List<UserDTO> getAllCouriers() {
        List<UserDTO> couriers = new ArrayList<UserDTO>();
        for (Courier c : courierDao.getAllCouriers()) {
            couriers.add(UserT.EntityToDTO(c));
        }
        return couriers;

    }

    @Override
    @Transactional
    @Secured({"ROLE_EMPL", "ROLE_COUR", "ROLE_ADMIN"})
    public List<UserDTO> getAllEmployees() {
        List<UserDTO> employees = new ArrayList<UserDTO>();
        for (Employee e : employeeDao.getAllEmployees()) {
            employees.add(UserT.EntityToDTO(e));
        }
        return employees;

    }

    @Override
    @Transactional
    @Secured({ "ROLE_ADMIN"})
    public boolean userContainsDelivery(UserDTO user, Long deliveryID) {
        if(user == null || user.getId()==null || user.getId()==0l || deliveryID == null || deliveryID ==0l) {
            throw new IllegalArgumentException("bad arugment user shoudnt be null or with id zero and deliverID not null and zero too");
        }
        UserDTO us = findEmployee(user.getId());
        if (us != null) {
            for (DeliveryDTO del : us.getDeliveries()) {
                if (del.getId() == deliveryID) {
                    return true;
                }
                return false;
            }
        } else {
            UserDTO cour = findCourier(user.getId());
            for (DeliveryDTO del : cour.getDeliveries()) {
                if (del.getId() == deliveryID) {
                    return true;
                }
                return false;
            }
        }

        return false;

    }
}
